Показаны сообщения с ярлыком разработка ПО. Показать все сообщения
Показаны сообщения с ярлыком разработка ПО. Показать все сообщения

Перед...

8 июл. 2013 г. | | |

Перед началом очередного проекта
Перед добавлением нового функционала
Перед улучшением работающего кода

Пост восторга, здравого смысла, недоумения и паники или образчик anti-usability

9 окт. 2012 г. | | |

Пользовательский интерфейс (GUI) - это лицо продукта. А usability - его душа. Так уж устроен человек, что клюёт на всё красивое. И даже наука есть, использующая этот баг человеческий. [1] Именно поэтому часто рисуется красивая обложка, а на проработку действительно важного аспекта продукта - usability - сил уже не хватает. И получаются монстры. Я не хочу сказать, что лучше делать что-то страшненькое, но удобное: среди пользователей встречаются не только гики, выросшие в консоли. Важен разумный компромис. Идеал - отличный GUI и проработанное usability. Но мы же реалисты и по поводу идеалов всё понимаем правильно. К сожалению, в последнее время слишком часто стали попадаться “странные штуки в красивых бумажках”. Но этот продукт - это верх какашности!

Парное программирование. Особое мнение.

31 авг. 2012 г. | | |

Принципы Эмерсона

30 авг. 2012 г. | | |



Не так давно на хабре промелькнула заметка, в которой 12 принципов эффективности Эмерсона были адаптированы для улучшения личной производительности фрилансера. В какой-то степени принципы, сформулированные Эмерсоном, универсальны, и применять их можно во многих сферах деятельности. Ниже приведены мои соображения по каждому из 12-ти пунктов в рамках разработки программного продукта. Сразу стоит оговориться, что многие вещи тесно связаны с методологией разработки, используемой в команде.

Субботнее чтение

11 авг. 2012 г. | | |

Одна за другой попались две статьи о превращениях. В первой статье баг успешно превратился в фичу, во второй - наоборот. И, если баг хорошо вжился в новое амплуа, то фича, замеченная в столь неподобающем поведении, превратилась в пятно на репутации.
Первая (перевод). Непреднамеренная концепция или "одно маленькое упущение, случившееся 40 лет назад".
Вторая. ICollection<T> и массивы или "Why the hell some read-only collection implements the Add() method?"

WTF?

28 июл. 2012 г. | | |


Есть ли жизнь после сдачи проекта?

21 мар. 2012 г. | | |


Размышления о качестве

18 янв. 2012 г. | | |

Читаю Э.Голдрат "Цель. Процесс непрерывного совершенствования". Долго откладывала эту книгу в сторону, но пришло и её время. Действительно, хорошая книга. Хоть и не it-тематики, но точки соприкосновения есть. Почитать эту книгу полезно всем, не только управленцам.

Если вы не производите качественный продукт, всё, что вы имеете в итоге - куча дорогостоящих ошибок.

Это далеко не новость. Но что такое качественный продукт? Первое, что приходит в голову, это программа без ошибок, т.е. тщательно оттестированный функционал, когда пользователь не переживает, что, ткнув не туда, можно завалить программу. Всю качественность функционала может затмить интерфейс, который не позволяет использовать продукт на все 100%. Т.е. интерфейс тоже должен быть качественным, продуманным, позволяя пользователю не тратить много времени на освоение. Это всё? Нет. Бек-сайд продукта - это код. И качественный код != код без багов. Качественный код - это совокупность характеристик, где одно из первых мест занимает качественная архитектура, позволяющая легко и безболезненно развивать продукт. Это тестируемость (testability) кода как подтверждение качества архитектуры.
И, конечно же, качественный продукт в состоянии выпустить только здоровая команда! (Однако обратное выражение не всегда верно) О влиянии отношений внутри команды на продукт была хорошая цитата тут

Здоровые отношения в группе разработки вносят непосредственный вклад в архитектуру системы. Нездоровые отношения и гипертрофированные самомнения порождают нездоровые продукты.

Качество продукта всегда коррелируется временем (сроками) и бюджетом (это внешние факторы) и профессионализмом команды (это внутренние факторы), и эти факторы очень тесно связаны. Бюджет прямо пропорционально влияет на профессионализм команды, а если ужать время, то даже профессионалы не смогут выдать качественный продукт. Тут вспоминается Ф.Брукс и его высказывание "9 женщин не родят ребёнка за 1 месяц" ("Мифический человеко-месяц").  А за то время, что команда новичков будет набираться опыта, продукт успеет устареть или надобность в нём отпадёт.
И напоследок - зачем вобще нужно это качество? Оно является одной из главных составляющих жизнеспособности - т.е. конкурентоспособности продукта, а значит, и успеха проекта.

Максим Цепков. Domain Driven Design - модель вместо требований

11 окт. 2011 г. | | |

Выступление Максима Цепкова на Летнем Аналитическом Фестивале - 2011. Иваново, 25 июня 2011 года.

8 советов

30 сент. 2011 г. | | |

Сегодня попались мне две статьи о том, как улучшить свой код. В сумме это дало 8 советов.

Аспектно-ориентированное программирование

13 июл. 2011 г. | | |

Что же такое  аспектно-ориентированное программирование? Ещё одна модная тенденция в мире разработки? Вики дает такое определение:

Аспе́ктно-ориенти́рованное программи́рование (АОП) — парадигма программирования, основанная на идее разделения функциональности для улучшения разбиения программы на модули.
Как-то знакомо звучит.

Рефакторинг - не панацея

25 мар. 2011 г. | | |

Недавно мне попалась фраза
Рефакторинг кода должен осуществляться до полного исчерпания его возможностей, поскольку наибольшая производительность может быть достигнута только в условиях работы с исходным кодом максимально высокого качества.

А так ли это? Попахивает  фанатизмом.

Насколько б рефакторинг не был полезной техникой, нужно понимать, что рефакторинг - это не панацея. Сколько не переименовывай названия методов и переменных, если архитектура кода из разряда "а всё, что плохо держится, мы подопрем деревянными распорками" (из байки "Если б программисты строили дома"), то лучше она от этого не станет. Проектирование ПО плюс постоянный рефакторинг при написании кода – это сильная связка. Плохо спроектированную систему будет трудно рефакторить – есть где разгуляться, да понять бы, за что сначала взяться - рефакторинг будет перекраивать ее, и, если браться за это, то явно не перед сдачей проекта проекта – это не то, на что следует тратить время. «Приближение срока окончания работ – единственный случай, когда можно отложить рефакториг, ссылаясь на недостаток времени.» - говорит М. Фаулер («Рефакторинг. Улучшение существующиего кода»).  
Но не стоит злоупотреблять этой техникой и в мирные времена, когда срок сдачи еще не близок, а руки чешутся что-нибудь переиначить. Рефакторинг кода к шаблонам может иметь не только положительные стороны, но и отрицательные, например, тотальное усложнение кода. Как и любой техникой, рефакторингом нужно использовать с умом. И вообще, ум нужно использовать, это тоже полезная техника ;)

Прелести байткода или зачем нужен обфускатор

10 мар. 2011 г. | | |

Прекрасная идея портируемости приложений, кроссплатформенности родила языки, использующие виртуальные машины, компилирующие промежуточный платформенно-независимый код (байт-код) в платформенно-специфичный код. Яркие примеры таких языков - Java, C#, VB, ActionScript etc. История, которую я хочу рассказать, будет именно о последнем, но общие моменты касаются всех языков, компилирующихся в промежуточный код.

История одного приложения

9 мар. 2011 г. | | |

История эта началась давно, в те времена, когда деревья были высокими и трава зеленее, да и макароны назывались правильно ... И была поставлена задача - написать простенькое приложеньице, дополнение к главной программе, состоящее буквально из одной формы.

Зачем нужен рефакторинг?

27 окт. 2010 г. | | |

Если вы только узнали, что это такое и не совсем понимаете, зачем оно нужно, то, скорее всего, после прочтения книги М.Фаулера "Рефакторинг", этот вопрос отпадет сам собой.
Если у вас уже есть опыт применения рефакторинга, но вы всё равно не понимаете, зачем это нужно, и считаете рефакторинг пустой тратой времени, то есть несколько вариантов объяснения:
а) либо вы - босс и считаете, что так программисты "валяют дурака" - вроде что-то и делают, но нового функционала - 0! Цель рефакторинга - не увеличение производительности кода, не сокращение расходуемой памяти, не ускорение алгоритмов вычислений - это все могут быть положительные побочные эффекты. Цель рефакторинга - структуризация и упрощение кода, приведение его в порядок, чтобы другой программист, который будет работать с ним после, не получил психологическую травму :)
б) либо вы применяете рефакторинг не там, где надо - еще раз почитайте М.Фаулера, другие книги (например, Д. Кериевски, С.Макконнелла и др.), разберите внимательно примеры... Вспомните, как часто вы слышите фразу (или сами ее говорите) "Этот код готов. Он не совсем идеален, зато работает!". Эдакий "скорокод"! Он ведь просто кричит "Help me! I wanna be refactored!" Вот тут можете смело оттачивать свои навыки!
в) либо вы считаете, что пишете идеальный код! - спуститесь с небес на землю, такого не бывает! Это была плохая новость. А теперь хорошая: вам есть, куда расти. Я считаю, что программист развивается, растет, когда находит все новые и новые пути оптимизации кода. Это значит, что он научился чему-то, увидел проблему в другом свете, и ее решение, раньше казавшееся сложным, теперь для него - само собой разумеющееся, элементарное. И с этими новыми знаниями программист может существенно улучшить старый код. Оглядываясь назад, думаю , как изящно можно было б решить ту или иную проблему с накопленными знаниями!
Помните, что любой код можно улучшить, главное в этом деле - не переборщить. И не стоит гнаться за принципом "совершенству нет предела", тут немного другая математика :)

IoC, DI, WTF?

10 сент. 2010 г. | | |

Давайте разберемся с этими загадочными абревиатурами и разницей между ними.

IoC (Inversion of Control) -
инверсия управления, один из принципов S.O.L.I.D., известна так же как Принцип обращения зависимостей (Dependency Inversion Principle, DIP). IoC - очень полезная техника, которая уменьшает связанность и придает гибкость разрабатываемому ПО. Принцип инверсии управления звучит так [wikipedia]:

Модули верхних уровней не должны зависеть от модулей нижних уровней. Оба типа модулей должны зависеть от абстракций. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
В своей статье Inversion of Control Containers and the Dependency Injection pattern Мартин Фаулер вводит понятие Dependency Injection (Dependency Injection) - внедрение зависимости - как разновидность IoC. Всего он выделяет три типа DI в зависимости от того, через что осуществляется DI:
1) Interface injection
2) Setter injection (пример)
3) Constructor injection (пример)

В чем измеряется качество кода?

20 авг. 2010 г. | | |

10 поговорок, которые должен знать каждый программист

16 июн. 2010 г. | | |

Перевод поста "10 Programming Proverbs Every Developer Should Know" Кевина Панга. Оригинал тут

Поговорки выражают общеизвестные истины или жизненные уроки в короткой и запоминающейся форме. Я считаю, что это отличный способ вести дела - и в личной жизни, и на работе. Поэтому я выделил 10 поговорок, которые каждый программист должен иметь в своем арсенале.

Топ 10 вещей, которые бесят программистов

15 июн. 2010 г. | | |

Перевод поста "Top 10 Things That Annoy Programmers" Кевина Панга. Оригинал тут

Комментарии в коде

30 мая 2010 г. | | |

Все мы не раз слышали, что код нужно комментировать, чтобы в нём потом можно было разобраться. Неопытные программисты часто возражают : "Это мой код, и я знаю, что он делает, и не забуду даже через полгода, что значит переменная k в выражении empS += k*arr[i] + bon[i]!" И при этом совершенно не учитывается, что кроме них, этот код могут править другие программисты - те бедолаги, которым придется сопровождать этот код. Но, опять же, комментарии, написанные, лишь бы написать, чтоб не цеплялись, - это еще хуже, чем отсутствие комментариев.

При плохом выполнении комментирование является пустой тратой времени и иногда причиняет вред.
С.Макконнелл

Например, в следующем коде комментарии совершенно бесполезны, потому что совершенно ничего не говорят:

int k = getKoeff(m); /*инициализируем переменную k значением, возвращаемым методом getKoeff */
double empS = 0.0; //инициализируем переменную empS нулем
for(int i=0; i<getWNub(m); i++)
{
empS +=k*arr[i] + bon[i]; //вычисляем сумму в цикле
}

Раз уж зашел разговор о полезности комментариев, то давайте определим цели - для чего вообще нужны комментарии в коде? Комментарии должны давать представление о том, что делает данный код, должны помогать читать его, так? На мой взгляд, самый лучший комментарий к коду - сам код.
Хороший код сам является самой лучшей документацией. Если код настолько плох, что требует объемных комментариев, попытайтесь сначала улучшить его.
С.Макконнелл
Я не призываю отказаться от комментариев в коде, я призываю к написанию ясного кода, который легко понять и модифицировать даже по прошествии длительного периода времени.
Что в моем понимании "ясный код"? Это, конечно же, самодокументирующийся код. Например, предыдущий кусок кода можно переписать так:

int koefficient = getSalaryKoefficient(monthNumber);
double employeeSalary = 0.0;
int workingDaysInCurrentMonth = getWorkingDaysNumber(monthNumber);
for(int dayNubmer=0; dayNumber<workingDaysInCurrentMonth; dayNubmer++)
{
employeeSalary +=koefficient*workingHours[dayNubmer] + dayBonus[dayNubmer];
}

Что изменилось в коде? Всего лишь имена переменных и методов, но этот код, в отличие от первого его варианта, понятен без комментариев. Имена переменных и методов говорят сами за себя, им не нужны никакие комментарии. Такими же должны делать имена классов, интерфейсов, констант, перечислений, элементов перечислений и т.д. О том, насколько важно правильно выбирать имена и как это делать, можно почитать в книге "Совершенный код" С. Макконнелла.
Почувствовав потребность написать комментарий, попробуйте сначала изменить структуру кода так, чтобы любые комментарии стали излишними...
М.Фаулер
Как менять структуру кода и когда это нужно делать, можно почитать в книге Мартина Фаулера "Рефакторинг. Улучшение существующего кода". Но, конечно же, есть несколько случаев, когда следовать вышеприведенной цитате не нужно. Во-первых, когда код делает не очевидные вещи, например (пример взят из книги "Совершенный код" С.Макконелла):

for(element = 0; element<elementCount; element++)
{
/*Для деления на 2 используется операция сдвига вправо. Это сокращает время выполнения цикла на 75% */
elementList[element] = elementList[element] >>1;
}

Вряд ли программист, который будет сопровождать этот код (даже сам автор по прошествии времени), сможет с первого раза догадаться, зачем тут нужен побитовый сдвиг вправо на единицу без комментария.
Во-вторых, стоит комментировать неявные значения, например:

//Цвет фона по умолчанию - белый
itemBgColor = Color.FromAGB(255,255,255);

Этот код лучше будет даже переписать следующим образом:

const Color DEFAULT_BG_COLOR = Color.FromAGB(255,255,255);
...
itemBgColor = DEFAULT_BG_COLOR;

Кроме того, следует комментировать использование недокументированных возможностей или исправление обнаруженных ошибок - ведь в следующих версиях системы этих возможностей может и не быть, а ошибки могут быть исправлены :)
Полезным может оказаться документирование ограничений, если они не заданы константами с говорящими именами, а используются в коде как есть - в виде чисел. Но с таким настоятельно советую бороться :)
В своей практике кроме всего выше перечисленного я предпочитаю давать краткое описание методу перед началом его кодирования, при этом использую очень замечательную возможность документирования кода в Visual Studio. Это выглядит так:

/// <summary>
/// Возвращает следующий по номеру ваучер по отношению к номеру текущего ваучера
/// </summary>
/// <returns>VoucherItem</returns>
public VoucherItem GetNextVoucherItem()
{
return VoucherRepository.GetNextVoucher(this.VoucherNumber);
}

Клиентский код, использующий методы моего класса, получает возможность использовать IntelliSense, что очень удобно.
И напоследок приведу такую цитату:
Пишите код, исходя из того, что все программисты, которые будут сопровождать вашу программу, - склонные к насилию психопаты, знающие, где вы живёте.
С.Макконнелл